文件的上传&预览&下载学习(一)

您所在的位置:网站首页 react pdf预览 文件的上传&预览&下载学习(一)

文件的上传&预览&下载学习(一)

2023-03-15 17:21| 来源: 网络整理| 查看: 265

注:主要是说明后端逻辑和数据库表设计

1.当前主流的几种文件上传&预览&下载方式 把文件直接存储在服务器 分布式存储OSS,比如阿里OSS、Minio 2.数据库表设计 由于文件都是跟业务关联的,比如评论里面掺杂评论图片,常规的设计就是在'评论表'添加上传'图片名称'字段和'图片相对路径',在上传成功后返回给前端 1.1 如果是加入多个文件的话,这种设计就不太合适:10个文件在评论表就需要加20个字段 1.2 针对'1.1'进行改进,建一种'文件信息表',设计字段'外键 fk_id'用来存储评论id(如果后续有商品图片也可以用这个存),这时候有需要考虑一个问题,id是根据什么生成的,是否唯一,如果是雪花ID就无需考虑这个问题,但如果是递增那极可能重复(商品id和评论id同时为1的情况);这时就还需要在'文件信息表'添加一个'外键类型 fk_type'作区分,比如评论就是comment,商品就是goods。然后把'图片名称'字段和'图片相对路径'放到'文件信息表'来(预览路径和下载路径可能不同,下载路径是绝对路径,预览路径为了防止用户直接访问服务器其他位置,做一层虚拟映射nginx)

1.3 可能还需要加一个'文件下载名称',由于文件可能是'数字+字母(可能是md5)'的形式(如果是手机拍摄),然后要按照一定的规则比如'订单编号-产品名称-用户昵称'生成

3.后端实现

1.直接使用Java下载到指定目录(现根据外键查询出绝对路径,在下载)

@Override public void downloadByOrderId(HttpServletResponse response, Long orderId, String fkType) throws IOException { String fileLocation = null; try{ // 一个订单只有一个报告pdf QueryWrapper fileUploadQueryWrapper = new QueryWrapper(); fileUploadQueryWrapper.eq("is_deleted","0"); fileUploadQueryWrapper.eq("fk_id",orderId); fileUploadQueryWrapper.eq("fk_type",fkType); FileUpload uploadEntity = uploadMapper.selectOne(fileUploadQueryWrapper); response.setHeader("content-type", "application/octet-stream"); response.setContentType("application/octet-stream"); //这边可以设置文件下载时的名字,我这边用的是文件原本的名字,可以根据实际场景设置 response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(uploadEntity.getOldName(), "UTF-8")); if(StrUtil.isNotBlank(uploadEntity.getLocation())){ fileLocation = uploadEntity.getLocation(); } logger.info("fileLocation: "+fileLocation); FileUtils.writeBytes(uploadEntity.getLocation(), response.getOutputStream()); }catch (Exception e){ logger.error("download error orderId: {} fkType: {} && fileLocation: {} msg: {}",orderId,fkType,fileLocation,e.getMessage()); } } public static void writeBytes(String filePath, OutputStream os) { FileInputStream fi = null; try { File file = new File(filePath); if (!file.exists()) { throw new FileNotFoundException(filePath); } fi = new FileInputStream(file); //TODO 扩大缓冲,多线程(请求的节点过多超时) byte[] b = new byte[8192]; int length; while ((length = fi.read(b,0,8192)) > 0) { os.write(b, 0, length); } } catch (Exception e) { e.printStackTrace(); } finally { if(os != null) { try { os.close(); }catch (IOException e) { e.printStackTrace(); } } if(fi != null) { try { fi.close(); }catch (IOException e) { e.printStackTrace(); } } } }

2.分布式存储Minio,参考博客:https://www.freesion.com/article/5069848586/ (下载和上面的方式相同 根据文件名先去Minio查询,获取输入流,然后下载)

文件的上传&预览&下载学习(一)的更多相关文章 PHP WAMP 文件上传 及 简单的上传预览

...... 使用特殊的表单类型file, 主(上传)页面:



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3